package tron

import (
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fisherman/common/http"
	"fisherman/main/cfg"
	"fmt"
	"github.com/btcsuite/btcutil/base58"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/tidwall/gjson"
	"math/big"
)

func generateParameter(base58Address string, amount float64) (data string) {
	//log.Infof("生成参数：%s", base58Address)
	hexAddress := base58.Decode(base58Address)
	trimmedAddress := hexAddress[1:21]
	paddedAddress := make([]byte, 32)
	copy(paddedAddress[32-len(trimmedAddress):], trimmedAddress)
	amountBigInt := big.NewInt(int64(amount * 1e6))
	amountBytes := amountBigInt.Bytes()
	paddedAmount := make([]byte, 32)
	copy(paddedAmount[32-len(amountBytes):], amountBytes)
	buffer := bytes.NewBuffer(paddedAddress)
	buffer.Write(paddedAmount)
	data = hex.EncodeToString(buffer.Bytes())
	return
}

// 查询转账订单结果
func queryTransferResult(txID string) (wait bool, err error) {
	rsp := http.PostJsonD(cfg.GetAPI()+"/wallet/gettransactionbyid", map[string]any{"value": txID, "visible": true})
	//log.Info(rsp)
	result := gjson.Get(rsp, "ret.0.contractRet").String()
	if result == "" {
		wait = true //外部继续等待
		err = fmt.Errorf("线上未发现订单")
		return
	}
	if result != "SUCCESS" {
		err = fmt.Errorf(rsp)
	}
	return
}

// 签名交易
func signTx(txJson, privateKey string) (signedTx map[string]any, err error) {
	//从相应数据里抽取 raw_data_hex
	var txData map[string]any
	err = json.Unmarshal([]byte(txJson), &txData)
	if err != nil {
		err = fmt.Errorf("解析json失败：%v", err)
		return
	}
	_, errOK := txData["Error"]
	if errOK {
		err = fmt.Errorf("无法签名，无效的交易数据(包含Error)：%s", txJson)
		return
	}
	_rawDataHex, ok := txData["raw_data_hex"]
	var rawDataHex string
	if ok {
		rawDataHex = _rawDataHex.(string)
	} else {
		transaction, transactionOK := txData["transaction"]
		if !transactionOK {
			err = fmt.Errorf("无法签名，无效的交易数据(无transaction字段)：%s", txJson)
			return
		}
		txData = transaction.(map[string]any)
		_rawDataHex, ok = txData["raw_data_hex"]
		if !ok {
			err = fmt.Errorf("传入的txJson根节点里找不到raw_data_hex：%s", txJson)
			return
		}
		rawDataHex = _rawDataHex.(string)
	}
	//解码交易数据
	rawTx, err := hex.DecodeString(rawDataHex)
	if err != nil {
		err = fmt.Errorf("执行hex.DecodeString(rawDataHex)失败：%v", err)
		return
	}
	//对交易数据计算哈希值
	hash := sha256.Sum256(rawTx) // TRON 使用 SHA-256 哈希
	hashBytes := hash[:]
	if len(hashBytes) != 32 {
		err = fmt.Errorf("hashBytes哈希值必须为32字节，当前大小为：%d", len(hashBytes))
		return
	}
	// 将私钥字符串转换为字节切片
	privKeyBytes, err := hex.DecodeString(privateKey)
	if err != nil {
		err = fmt.Errorf("执行hex.DecodeString(privateKey)失败：%v", err)
		return
	}
	// 从私钥字节中恢复公钥
	privateKeyECDSA, err := crypto.ToECDSA(privKeyBytes)
	if err != nil {
		err = fmt.Errorf("执行crypto.ToECDSA(privKeyBytes)失败：%v", err)
		return
	}
	// 使用私钥签名交易
	signature, err := crypto.Sign(hashBytes, privateKeyECDSA)
	if err != nil {
		err = fmt.Errorf("执行crypto.Sign(hashBytes, privateKeyECDSA)失败：%v", err)
		return
	}
	// 将签名附加到交易数据
	txData["signature"] = []string{hex.EncodeToString(signature)}
	signedTx = txData
	return
}

func broadcastTx(signedTx map[string]any) (err error) {
	rsp := http.PostJsonD(cfg.GetAPI()+"/wallet/broadcasttransaction", signedTx)
	//log.Infof("广播响应：%s", broadcastRsp)
	if !gjson.Get(rsp, "result").Bool() {
		err = fmt.Errorf("广播交易失败：%v", rsp)
		return
	}
	return
}
